package com.lcx.demo.nioday01;


import org.junit.Test;

import java.nio.ByteBuffer;

/*
*  一、缓冲区（Buffer):在java NIO 中负责数据的存储。缓冲区就是数组，用于存储不同数据类型的数据
*
* 根据数据类型不同（boolean)除外，提供了相对应的缓冲区
* ByteBuffer
* LongBuffer
* ShortBuffer
* IntBuffer
* FloatBuffer
* DoubleBuffer
* CharBuffer
*
* 上述缓冲区管理方式几乎一致 通过allocate() 获取缓冲区
*
* 二，缓存区存储数据的两个核心方法
* put():存入缓冲区
* get()： 获取缓冲区中的数据
*
* 三， 缓冲区中的四个核心属性
* capacity: 容量，表示缓冲区中最大存储数据的容量。一旦声明不能改变
* limit: 界限 表示缓冲区中可以操作数据的大小。（limit 后数据不能进行读写）
* position: 位置，表示缓冲区正在操作数据的位置
* mark: 标记，表示记录当前position的位置，可以通过reset（） 恢复到mark的位置
* 0<=mark<=position<=limit<=capacity
*
*
* 四、直接缓冲区与非直接换缓冲区
* 非直接缓冲区： 通过allocate()方法分配缓冲区，将缓冲区建立在jvm的内存中
* 直接缓冲区： 通过allocateDirect()方法分配直接缓冲区，将缓冲区建立在物理内存中，提高效率
*/
public class TestBuffer {

    @Test
    public void test3(){
        //分配直接缓冲区
        ByteBuffer buf = ByteBuffer.allocateDirect(1024);
        //判断是否时直接缓冲区
        System.out.println(buf.isDirect());
    }
    @Test
    public void test2(){
        String str = "abcde";
        ByteBuffer buf = ByteBuffer.allocate(1024);
        buf.put(str.getBytes());
        buf.flip();
        byte[] dst = new byte[buf.limit()];
        buf.get(dst,0,2);
        System.out.println(new String(dst,0,2));
        System.out.println(buf.position());

        //mark():标记
        buf.mark();

        buf.get(dst,2,2);
        System.out.println(new String(dst,2,2));
        System.out.println(buf.position());

        //reset()： 恢复到mark的位置
        buf.reset();
        System.out.println(buf.position());

        //判断缓冲区中是否还有可以操作的数据  如果有还有几个
        if (buf.hasRemaining()){
            System.out.println(buf.remaining());
        }
    }

    @Test
    public void test1(){
        String str = "abcde";

        //1.分配一个指定大小的缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);

        System.out.println("================allocate()============");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());

        //利用put存入数据到缓冲区中
        buf.put(str.getBytes());
        System.out.println("================put()============");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());

        //切换成读取数据的模式
        buf.flip();
//        buf.put(str.getBytes());
        System.out.println("================flip()============");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());

        //利用get()读取数据
        byte[] dst  = new byte[buf.limit()];
        System.out.println(buf.remaining());
        buf.get(dst);
        System.out.println(new String(dst,0,dst.length));

        System.out.println("================get()============");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());

        //rewind() 可重复读
        buf.rewind();
        System.out.println("================rewind()============");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());

        //清空缓冲区 缓冲区中的数据还在，处于“被遗忘”状态
        buf.clear();
        System.out.println("================clear()============");
        System.out.println(buf.position());
        System.out.println(buf.limit());
        System.out.println(buf.capacity());
        System.out.println((char)buf.get());
    }
}
